<template>
  <div class="app-container p-6 file-manager">
    <div class="card">
      <div class="d-flex justify-between items-center mb-4">
        <div class="text-primary" style="font-weight:600;">文件管理</div>
        <div class="d-flex" style="gap:8px;">
          <el-button type="primary" @click="showFileUploadDialog = true">
            <el-icon><document /></el-icon>
            文件上传
          </el-button>
          <el-button type="success" @click="showImageUploadDialog = true">
            <el-icon><picture /></el-icon>
            图片上传
          </el-button>
        </div>
      </div>

      <div class="bg-panel radius-lg p-4 mb-4">
        <el-form :inline="true">
          <el-form-item label="关键词">
            <el-input 
              v-model="query.keyword" 
              placeholder="搜索文件名/描述" 
              clearable 
              @keyup.enter="loadData" 
              style="width: 260px;"
            >
              <template #prefix>
                <el-icon><search /></el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="loadData">
              <el-icon><refresh /></el-icon>
              查询
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <div class="bg-panel radius-lg p-0">
        <el-table :data="list" border stripe style="width: 100%" v-loading="loading">
          <el-table-column label="文件" min-width="320">
            <template #default="{ row }">
              <div class="file-cell">
                <template v-if="row.mimeType?.startsWith('image/') && thumbUrlMap[row.id]">
                  <el-image
                    :src="thumbUrlMap[row.id]"
                    fit="cover"
                    class="file-thumb"
                    lazy
                  >
                    <template #error>
                      <el-icon class="file-icon file-image"><picture /></el-icon>
                    </template>
                  </el-image>
                </template>
                <template v-else>
                  <el-icon class="file-icon" :class="getFileIconClass(row.mimeType)">
                    <component :is="getFileIconComponent(row.mimeType)" />
                  </el-icon>
                </template>
                <div class="file-info">
                  <div class="file-name">{{ row.displayName || row.originalName }}</div>
                  <div v-if="row.originalName && row.originalName !== row.displayName" class="file-path">{{ row.originalName }}</div>
                </div>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="mimeType" label="类型" width="140">
            <template #default="{ row }">
              <el-tag :type="getFileTypeTagType(row.mimeType)" size="small">
                {{ getFileTypeText(row.mimeType) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="humanReadableSize" label="大小" width="120" />
          <el-table-column prop="uploaderName" label="上传者" width="140" />
          <el-table-column prop="uploadTime" label="上传时间" width="180">
            <template #default="{ row }">
              {{ formatDate(row.uploadTime) }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="520" fixed="right" align="center">
            <template #default="{ row }">
              <el-button type="primary" size="small" :icon="View" @click="previewFile(row)">预览</el-button>
              <el-button type="success" size="small" :icon="Download" @click="downloadFile(row)">下载</el-button>
              <el-button size="small" :icon="Edit" @click="renameFile(row)">重命名</el-button>
              <el-popconfirm title="确定删除该文件吗？" @confirm="removeFile(row)">
                <template #reference>
                  <el-button type="danger" size="small" :icon="Delete">删除</el-button>
                </template>
              </el-popconfirm>
              <el-button size="small" :icon="Share" @click="openShareManager(row)">分享</el-button>
              <el-button size="small" :icon="Collection" @click="openVersionManager(row)">版本</el-button>
            </template>
          </el-table-column>
        </el-table>

        <div class="d-flex justify-between items-center p-4">
          <el-pagination
            v-show="total > 0"
            :current-page="query.current"
            :page-size="query.size"
            :total="total"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </div>

    <!-- 文件上传对话框 -->
    <el-dialog
      v-model="showFileUploadDialog"
      title="文件上传"
      width="600px"
      append-to-body
      @close="handleFileUploadClose"
    >
      <div class="upload-dialog-content">
                 <FileUpload
                   v-model="uploadedFiles"
                   :multiple="true"
                   :limit="10"
                   :max-size="50"
                   :drag="true"
                   :auto-upload="false"
                   accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
                   tip="支持拖拽上传，文档、表格、演示文稿等，单个文件不超过50MB"
                   business-type="document"
                   :show-custom-file-list="true"
                   @success="onFileUploadSuccess"
                   @error="onUploadError"
                 />
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showFileUploadDialog = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 图片上传对话框 -->
    <el-dialog
      v-model="showImageUploadDialog"
      title="图片上传"
      width="700px"
      append-to-body
      @close="handleImageUploadClose"
    >
      <div class="upload-dialog-content">
                 <ImageUpload
                   v-model="uploadedImages"
                   :multiple="true"
                   :limit="9"
                   :max-size="10"
                   :item-size="100"
                   :auto-upload="false"
                   :show-image-info="false"
                   placeholder-text="添加图片"
                   tip="支持 JPG、PNG、GIF 等格式，单张不超过10MB"
                   business-type="image"
                   @success="onImageUploadSuccess"
                   @error="onUploadError"
                   @preview="onImagePreview"
                 />
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showImageUploadDialog = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 图片预览对话框 -->
    <el-dialog
      v-model="previewVisible"
      :title="currentPreviewFile?.displayName || '文件预览'"
      width="80%"
      append-to-body
      class="preview-dialog"
      @close="handlePreviewClose"
    >
      <div class="preview-container">
        <img 
          v-if="currentPreviewFile?.mimeType?.startsWith('image/')"
          :src="currentPreviewUrl"
          :alt="currentPreviewFile?.displayName"
          class="preview-image"
        />
        <div v-else class="preview-placeholder">
          <el-icon class="preview-icon"><document /></el-icon>
          <p>该文件类型不支持在线预览</p>
          <el-button type="primary" @click="downloadFile(currentPreviewFile!)">
            下载文件
          </el-button>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="previewVisible = false">关闭</el-button>
          <el-button type="primary" @click="downloadFile(currentPreviewFile!)">
            <el-icon><download /></el-icon>
            下载
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElDialog } from 'element-plus'
import {
  Search,
  Refresh,
  Download,
  Edit,
  Delete,
  Document,
  Picture,
  VideoPlay,
  Service,
  View,
  Share,
  Collection
} from '@element-plus/icons-vue'
import { FileUpload, ImageUpload } from '@/components/index'
import { fileApi } from '@/api/file'
import axios from 'axios'
import { useUserStore } from '@/stores/user'
import type { FileInfoVO } from '@/api/file'
import type { UploadFile } from 'element-plus'

// 用户状态
const userStore = useUserStore()
const router = useRouter()

// 基础数据
const loading = ref(false)
const list = ref<FileInfoVO[]>([])
const total = ref(0)
const query = ref({ 
  current: 1, 
  size: 10, 
  keyword: ''
})

// 上传相关
const showFileUploadDialog = ref(false)
const showImageUploadDialog = ref(false)
const uploadedFiles = ref<UploadFile[]>([])
const uploadedImages = ref<UploadFile[]>([])

// 预览相关
const previewVisible = ref(false)
const currentPreviewFile = ref<FileInfoVO>()
const currentPreviewUrl = ref('')

// 图片缩略图缓存（避免重复请求）
const thumbUrlMap = ref<Record<string, string>>({})

const apiBase = import.meta.env.VITE_API_BASE_URL || '/api'

const buildAuthHeaders = () => ({
  'Authorization': `Bearer ${userStore.token}`,
  'X-Session-Id': userStore.sessionId || '',
  'X-Tenant-Id': userStore.userInfo?.tenantId || ''
})

const revokeAllThumbUrls = () => {
  Object.values(thumbUrlMap.value).forEach(url => {
    try { url && window.URL.revokeObjectURL(url) } catch {}
  })
  thumbUrlMap.value = {}
}

const fetchThumbnail = async (file: FileInfoVO) => {
  try {
    const response = await axios.get(`${apiBase}/file/fileinfo/download/${file.id}` , {
      responseType: 'blob',
      headers: buildAuthHeaders()
    })
    const objectUrl = window.URL.createObjectURL(response.data)
    thumbUrlMap.value[file.id] = objectUrl
  } catch (e) {
    // 忽略缩略图加载失败，使用图标兜底
  }
}

// 加载数据
const loadData = async () => {
  loading.value = true
  try {
    const { data } = await fileApi.getFileList(query.value)
    list.value = data?.records || []
    total.value = data?.total || 0
    // 预取图片缩略图（带鉴权，生成 blob URL）
    revokeAllThumbUrls()
    await Promise.all(
      list.value
        .filter(f => f.mimeType?.startsWith('image/'))
        .map(async f => {
          if (!thumbUrlMap.value[f.id]) {
            await fetchThumbnail(f)
          }
        })
    )
  } finally {
    loading.value = false
  }
}

// 上传成功回调
const onFileUploadSuccess = (file: UploadFile, response: any) => {
  ElMessage.success(`文件 ${file.name} 上传成功`)
  loadData() // 刷新列表
}

const onImageUploadSuccess = (file: UploadFile, response: any) => {
  ElMessage.success(`图片 ${file.name} 上传成功`)
  loadData() // 刷新列表
}

// 上传错误回调
const onUploadError = (error: any, file: UploadFile) => {
  ElMessage.error(`文件 ${file.name} 上传失败: ${error.message}`)
}

// 图片预览回调
const onImagePreview = (file: UploadFile) => {
  ElMessage.info(`预览图片: ${file.name}`)
}

// 对话框关闭处理
const handleFileUploadClose = () => {
  uploadedFiles.value = []
}

const handleImageUploadClose = () => {
  uploadedImages.value = []
}

// 文件下载
const downloadFile = async (file: FileInfoVO) => {
  try {
    const response = await axios.get(`${import.meta.env.VITE_API_BASE_URL || '/api'}/file/fileinfo/download/${file.id}`, {
      responseType: 'blob',
      headers: {
        'Authorization': `Bearer ${userStore.token}`,
        'X-Session-Id': userStore.sessionId || '',
        'X-Tenant-Id': userStore.userInfo?.tenantId || ''
      }
    })
    
    const blob = new Blob([response.data])
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = file.displayName || file.originalName || 'download'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    ElMessage.success('下载成功')
  } catch (e: any) {
    console.error('下载失败:', e)
    if (e?.response?.status === 401) {
      ElMessage.error('登录已过期，请重新登录')
    } else {
      ElMessage.error(e?.response?.data?.message || e?.message || '下载失败')
    }
  }
}

// 文件预览
const previewFile = async (file: FileInfoVO) => {
  try {
    if (file.mimeType?.startsWith('image/')) {
      // 图片预览
      const response = await axios.get(`${import.meta.env.VITE_API_BASE_URL || '/api'}/file/fileinfo/download/${file.id}`, {
        responseType: 'blob',
        headers: {
          'Authorization': `Bearer ${userStore.token}`,
          'X-Session-Id': userStore.sessionId || '',
          'X-Tenant-Id': userStore.userInfo?.tenantId || ''
        }
      })
      
      const blob = new Blob([response.data])
      currentPreviewUrl.value = window.URL.createObjectURL(blob)
      currentPreviewFile.value = file
      previewVisible.value = true
    } else {
      // 非图片文件提示下载
      ElMessage.warning('该文件不支持在线预览，将为您下载')
      downloadFile(file)
    }
  } catch (e: any) {
    console.error('预览失败:', e)
    if (e?.response?.status === 401) {
      ElMessage.error('登录已过期，请重新登录')
    } else {
      ElMessage.error(e?.response?.data?.message || e?.message || '预览失败')
    }
  }
}

// 文件重命名
const renameFile = async (file: FileInfoVO) => {
  const newName = prompt('请输入新名称', file.displayName)
  if (!newName || newName === file.displayName) return
  
  try {
    const { data } = await fileApi.renameFile(file.id, newName)
    if (data) {
      ElMessage.success('重命名成功')
      loadData()
    }
  } catch (e: any) {
    ElMessage.error(e?.message || '重命名失败')
  }
}

// 删除文件
const removeFile = async (file: FileInfoVO) => {
  try {
    const { data } = await fileApi.deleteFile(file.id)
    if (data) {
      ElMessage.success('删除成功')
      loadData()
    }
  } catch (e: any) {
    ElMessage.error(e?.message || '删除失败')
  }
}

// 打开分享与版本管理（带 fileId）
const openShareManager = (file: FileInfoVO) => {
  router.push({ path: '/system/file/share', query: { fileId: file.id } })
}

const openVersionManager = (file: FileInfoVO) => {
  router.push({ path: '/system/file/version', query: { fileId: file.id } })
}

// 分页处理
const handleCurrentChange = (page: number) => {
  query.value.current = page
  loadData()
}

const handleSizeChange = (size: number) => {
  query.value.size = size
  query.value.current = 1
  loadData()
}

// 文件类型相关工具函数
const getFileIconComponent = (mimeType?: string) => {
  if (!mimeType) return Document
  if (mimeType.startsWith('image/')) return Picture
  if (mimeType.startsWith('video/')) return VideoPlay
  if (mimeType.startsWith('audio/')) return Service
  return Document
}

const getFileIconClass = (mimeType?: string) => {
  if (!mimeType) return 'file-document'
  if (mimeType.startsWith('image/')) return 'file-image'
  if (mimeType.startsWith('video/')) return 'file-video'
  if (mimeType.startsWith('audio/')) return 'file-audio'
  return 'file-document'
}

const getFileTypeText = (mimeType?: string) => {
  if (!mimeType) return '文件'
  if (mimeType.startsWith('image/')) return '图片'
  if (mimeType.startsWith('video/')) return '视频'
  if (mimeType.startsWith('audio/')) return '音频'
  if (mimeType.includes('pdf')) return 'PDF'
  if (mimeType.includes('word') || mimeType.includes('document')) return '文档'
  if (mimeType.includes('sheet') || mimeType.includes('excel')) return '表格'
  if (mimeType.includes('presentation') || mimeType.includes('powerpoint')) return '演示'
  return '文件'
}

const getFileTypeTagType = (mimeType?: string): 'success' | 'warning' | 'info' | 'danger' | 'primary' | undefined => {
  if (!mimeType) return undefined
  if (mimeType.startsWith('image/')) return 'success'
  if (mimeType.startsWith('video/')) return 'warning'
  if (mimeType.startsWith('audio/')) return 'info'
  return undefined
}

// 格式化日期
const formatDate = (dateString?: string) => {
  if (!dateString) return '-'
  const date = new Date(dateString)
  return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}

// 监听预览对话框关闭，清理blob URL
const handlePreviewClose = () => {
  if (currentPreviewUrl.value) {
    window.URL.revokeObjectURL(currentPreviewUrl.value)
    currentPreviewUrl.value = ''
  }
  currentPreviewFile.value = undefined
}

// 挂载时加载数据
onMounted(loadData)

onBeforeUnmount(() => {
  // 清理预览和缩略图的 blob URL
  if (currentPreviewUrl.value) {
    try { window.URL.revokeObjectURL(currentPreviewUrl.value) } catch {}
  }
  revokeAllThumbUrls()
})
</script>

<!-- 样式已迁移到 @/styles/modules/file.scss -->
